package com.mini.grpc.common;

/**
 * Status表示RPC调用的结果状态。
 * 
 * <p>类似于HTTP状态码，Status提供了一组标准的错误代码，可以用于表示RPC调用的结果。
 */
public final class Status {

    /**
     * 状态码枚举
     */
    public enum Code {
        /**
         * 调用成功
         */
        OK(0),
        
        /**
         * 调用被取消
         */
        CANCELLED(1),
        
        /**
         * 未知错误
         */
        UNKNOWN(2),
        
        /**
         * 无效参数
         */
        INVALID_ARGUMENT(3),
        
        /**
         * 调用超时
         */
        DEADLINE_EXCEEDED(4),
        
        /**
         * 资源不存在
         */
        NOT_FOUND(5),
        
        /**
         * 资源已存在
         */
        ALREADY_EXISTS(6),
        
        /**
         * 权限不足
         */
        PERMISSION_DENIED(7),
        
        /**
         * 资源耗尽
         */
        RESOURCE_EXHAUSTED(8),
        
        /**
         * 前置条件失败
         */
        FAILED_PRECONDITION(9),
        
        /**
         * 调用被中止
         */
        ABORTED(10),
        
        /**
         * 超出范围
         */
        OUT_OF_RANGE(11),
        
        /**
         * 功能未实现
         */
        UNIMPLEMENTED(12),
        
        /**
         * 内部错误
         */
        INTERNAL(13),
        
        /**
         * 服务不可用
         */
        UNAVAILABLE(14),
        
        /**
         * 数据丢失
         */
        DATA_LOSS(15),
        
        /**
         * 未认证
         */
        UNAUTHENTICATED(16);
        
        private final int value;
        
        Code(int value) {
            this.value = value;
        }
        
        /**
         * 获取状态码的整数值
         *
         * @return 状态码的整数值
         */
        public int value() {
            return value;
        }
        
        /**
         * 根据整数值获取对应的状态码
         *
         * @param value 整数值
         * @return 对应的状态码，如果不存在则返回UNKNOWN
         */
        public static Code fromValue(int value) {
            for (Code code : values()) {
                if (code.value == value) {
                    return code;
                }
            }
            return UNKNOWN;
        }
    }
    
    private final Code code;
    private final String description;
    private final Throwable cause;
    
    private Status(Code code, String description, Throwable cause) {
        this.code = code;
        this.description = description;
        this.cause = cause;
    }
    
    /**
     * 获取状态码
     *
     * @return 状态码
     */
    public Code getCode() {
        return code;
    }
    
    /**
     * 获取描述信息
     *
     * @return 描述信息
     */
    public String getDescription() {
        return description;
    }
    
    /**
     * 获取导致此状态的异常
     *
     * @return 异常，可能为null
     */
    public Throwable getCause() {
        return cause;
    }
    
    /**
     * 检查状态是否为OK
     *
     * @return 如果状态为OK则返回true，否则返回false
     */
    public boolean isOk() {
        return code == Code.OK;
    }
    
    /**
     * 使用当前状态创建一个异常
     *
     * @return 基于当前状态的StatusRuntimeException
     */
    public StatusRuntimeException asRuntimeException() {
        return new StatusRuntimeException(this);
    }
    
    /**
     * 使用当前状态和元数据创建一个异常
     *
     * @param metadata 元数据
     * @return 基于当前状态和元数据的StatusRuntimeException
     */
    public StatusRuntimeException asRuntimeException(Metadata metadata) {
        return new StatusRuntimeException(this, metadata);
    }
    
    /**
     * 创建一个带有描述信息的新状态
     *
     * @param description 描述信息
     * @return 新的Status实例
     */
    public Status withDescription(String description) {
        return new Status(this.code, description, this.cause);
    }
    
    /**
     * 创建一个带有异常的新状态
     *
     * @param cause 异常
     * @return 新的Status实例
     */
    public Status withCause(Throwable cause) {
        return new Status(this.code, this.description, cause);
    }
    
    @Override
    public String toString() {
        return String.format("Status{code=%s, description=%s, cause=%s}",
                code, description, cause != null ? cause.getClass().getName() : "null");
    }
    
    // 静态工厂方法
    
    /**
     * 创建一个OK状态
     *
     * @return OK状态
     */
    public static Status OK = fromCode(Code.OK);
    
    /**
     * 创建一个CANCELLED状态
     *
     * @return CANCELLED状态
     */
    public static Status CANCELLED = fromCode(Code.CANCELLED);
    
    /**
     * 创建一个UNKNOWN状态
     *
     * @return UNKNOWN状态
     */
    public static Status UNKNOWN = fromCode(Code.UNKNOWN);
    
    /**
     * 创建一个INVALID_ARGUMENT状态
     *
     * @return INVALID_ARGUMENT状态
     */
    public static Status INVALID_ARGUMENT = fromCode(Code.INVALID_ARGUMENT);
    
    /**
     * 创建一个DEADLINE_EXCEEDED状态
     *
     * @return DEADLINE_EXCEEDED状态
     */
    public static Status DEADLINE_EXCEEDED = fromCode(Code.DEADLINE_EXCEEDED);
    
    /**
     * 创建一个NOT_FOUND状态
     *
     * @return NOT_FOUND状态
     */
    public static Status NOT_FOUND = fromCode(Code.NOT_FOUND);
    
    /**
     * 创建一个ALREADY_EXISTS状态
     *
     * @return ALREADY_EXISTS状态
     */
    public static Status ALREADY_EXISTS = fromCode(Code.ALREADY_EXISTS);
    
    /**
     * 创建一个PERMISSION_DENIED状态
     *
     * @return PERMISSION_DENIED状态
     */
    public static Status PERMISSION_DENIED = fromCode(Code.PERMISSION_DENIED);
    
    /**
     * 创建一个RESOURCE_EXHAUSTED状态
     *
     * @return RESOURCE_EXHAUSTED状态
     */
    public static Status RESOURCE_EXHAUSTED = fromCode(Code.RESOURCE_EXHAUSTED);
    
    /**
     * 创建一个FAILED_PRECONDITION状态
     *
     * @return FAILED_PRECONDITION状态
     */
    public static Status FAILED_PRECONDITION = fromCode(Code.FAILED_PRECONDITION);
    
    /**
     * 创建一个ABORTED状态
     *
     * @return ABORTED状态
     */
    public static Status ABORTED = fromCode(Code.ABORTED);
    
    /**
     * 创建一个OUT_OF_RANGE状态
     *
     * @return OUT_OF_RANGE状态
     */
    public static Status OUT_OF_RANGE = fromCode(Code.OUT_OF_RANGE);
    
    /**
     * 创建一个UNIMPLEMENTED状态
     *
     * @return UNIMPLEMENTED状态
     */
    public static Status UNIMPLEMENTED = fromCode(Code.UNIMPLEMENTED);
    
    /**
     * 创建一个INTERNAL状态
     *
     * @return INTERNAL状态
     */
    public static Status INTERNAL = fromCode(Code.INTERNAL);
    
    /**
     * 创建一个UNAVAILABLE状态
     *
     * @return UNAVAILABLE状态
     */
    public static Status UNAVAILABLE = fromCode(Code.UNAVAILABLE);
    
    /**
     * 创建一个DATA_LOSS状态
     *
     * @return DATA_LOSS状态
     */
    public static Status DATA_LOSS = fromCode(Code.DATA_LOSS);
    
    /**
     * 创建一个UNAUTHENTICATED状态
     *
     * @return UNAUTHENTICATED状态
     */
    public static Status UNAUTHENTICATED = fromCode(Code.UNAUTHENTICATED);
    
    /**
     * 从状态码创建一个状态
     *
     * @param code 状态码
     * @return 对应的状态
     */
    public static Status fromCode(Code code) {
        return new Status(code, null, null);
    }
    
    /**
     * 从状态码和描述信息创建一个状态
     *
     * @param code 状态码
     * @param description 描述信息
     * @return 对应的状态
     */
    public static Status fromCodeWithDescription(Code code, String description) {
        return new Status(code, description, null);
    }
    
    /**
     * 从异常创建一个状态
     *
     * @param throwable 异常
     * @return 对应的状态
     */
    public static Status fromThrowable(Throwable throwable) {
        if (throwable instanceof StatusRuntimeException) {
            return ((StatusRuntimeException) throwable).getStatus();
        }
        
        // 根据异常类型映射到相应的状态码
        if (throwable instanceof IllegalArgumentException) {
            return INVALID_ARGUMENT.withCause(throwable);
        } else if (throwable instanceof SecurityException) {
            return PERMISSION_DENIED.withCause(throwable);
        } else if (throwable instanceof UnsupportedOperationException) {
            return UNIMPLEMENTED.withCause(throwable);
        } else if (throwable instanceof InterruptedException) {
            return CANCELLED.withCause(throwable);
        } else {
            return UNKNOWN.withCause(throwable);
        }
    }
} 